// Package dbservice
// @Author: zhangdi
// @File: Config
// @Version: 1.0.0
// @Date: 2023/5/19 10:07
package dbservice

import (
	"fmt"
	"ideatools/application/constant"
	"ideatools/application/constant/enums"
	"ideatools/application/db/dbdto"
	"ideatools/application/db/repository"
	"ideatools/application/db/sqllite"
	"ideatools/application/dto"
	"ideatools/application/pkgs/mylog"
	"ideatools/application/pkgs/utils"
	"ideatools/application/pkgs/where"
	"strconv"
	"strings"
	"sync"
)

// 锁住repo
var muConfig sync.Mutex

type DbConfigService struct {
	repo *repository.ConfigRepository
	//Cache *sync.Map //内存缓存 //内存缓存
}

// 全局变量 全局共享
var configCache *sync.Map = &sync.Map{}

func NewDbConfigService() *DbConfigService {
	repo_ := repository.NewConfigRepository(sqllite.GetDb())
	s := &DbConfigService{
		//Cache: &sync.Map{}, //内存缓存,
		repo: repo_,
	}

	//一次性取出所有数据
	wheres := where.Format(where.Opt("id", ">", 0))
	list, err := repo_.FindListByWhere(wheres)
	if err != nil {
		return nil
	}

	for _, config := range list {
		s.SaveToCache(config.ConfigKey, config.ConfigValue)
	}

	return s
}

// Set 设置值
func (s *DbConfigService) Set(k, v string) dto.RespData {
	return s.SetKVT(k, v, constant.ConfigTypeDefault)
}

func (s *DbConfigService) SetBool(k string, flag bool, typ string) dto.RespData {
	BoolStr := "0"
	if flag {
		BoolStr = "1"
	}
	return s.SetKVT(k, BoolStr, typ)
}

func (s *DbConfigService) GetBool(k string) bool {
	BoolStr := s.Get(k)
	if BoolStr == enums.BoolYes {
		return true
	}
	return false
}

func (s *DbConfigService) SetNumber(k string, val int, typ string) dto.RespData {

	return s.SetKVT(k, strconv.Itoa(val), typ)
}

func (s *DbConfigService) GetNumber(k string) int {
	Str := s.Get(k)
	if Str == "" {
		return 0
	}
	num, err := strconv.Atoi(Str)
	if err != nil {
		fmt.Println("GetNumber() 将一个字符串转成int转换失败：", err)
		return num
	}

	return num
}

// SetKVT 设置值，带类型
func (s *DbConfigService) SetKVT(k, v, typ string) dto.RespData {
	//加锁--互斥锁
	muConfig.Lock()
	defer muConfig.Unlock()

	s.SaveToCache(k, v)
	wheres := where.Format(
		where.Opt("config_key", "=", k),
	)
	info, err := s.repo.FindOneByWhere(wheres)
	if err == nil && info != nil {
		err := s.repo.UpdateValue(k, v, typ)
		if err != nil {
			return dto.RespError(err.Error())
		} else {
			return dto.RespOk("设置完成", s.Get(k))
		}
	} else {
		return s.CreateConfig(&dbdto.ConfigAdd{
			ConfigKey:   k,
			ConfigValue: v,
			ConfigType:  typ,
		})
	}
}

// Get 获取值--底层
func (s *DbConfigService) Get(k string) string {
	if s.ReadByCache(k) != "" {
		return s.ReadByCache(k) //使用内存中的数据
	}
	info := s.GetInfo(k)
	if info == nil {
		return ""
	}
	s.SaveToCache(k, info.ConfigValue)
	return info.ConfigValue
}

// GetDefault 获取一个值，没有则返回默认值
func (s *DbConfigService) GetDefault(k string, defaultVal string) string {
	res := s.Get(k)
	if strings.TrimSpace(res) == "" {
		return defaultVal
	}
	return res
}

func (s *DbConfigService) GetInfo(k string) *dbdto.ConfigInfo {
	wheres := where.Format(
		where.Opt("config_key", "=", k),
	)

	info, err := s.repo.FindOneByWhere(wheres)
	if err != nil {
		mylog.Error(err.Error())
		return nil
	}
	res := &dbdto.ConfigInfo{}
	utils.DtoToEntity(info, res)
	return res
}

// CreateConfig 创建一个工具
func (s *DbConfigService) CreateConfig(DtoConfigCreate *dbdto.ConfigAdd) dto.RespData {
	info, _ := s.repo.FindOneByWhere(where.Format(where.Opt("config_key", "=", DtoConfigCreate.ConfigKey)))
	if info != nil {
		return dto.RespError("该名称已存在，换一个吧~")
	}
	err := s.repo.Create(DtoConfigCreate)
	if err != nil {
		mylog.Error("CreateConfig:" + err.Error())
		return dto.RespError(err.Error())
	}

	return dto.RespOk("创建完成", DtoConfigCreate)
}

// UpdateConfig 更新配置
func (s *DbConfigService) UpdateConfig(DtoConfigUpdate *dbdto.ConfigUpdate) dto.RespData {
	err := s.repo.Update(DtoConfigUpdate)
	if err != nil {
		return dto.RespError(err.Error())
	}
	return dto.RespOk("修改完成", DtoConfigUpdate)
}

// GetListByType 获取某个type下的配置列表
func (s *DbConfigService) GetListByType(ConfigType string) []*dbdto.ConfigKV {
	wheres := where.Format(where.Opt("config_type", "=", ConfigType))
	List, err := s.repo.FindListByWhere(wheres)
	if err != nil {
		mylog.Error(err.Error())
		return nil
	}
	res := make([]*dbdto.ConfigKV, 0)
	for _, item := range List {
		kv := &dbdto.ConfigKV{}
		utils.DtoToEntity(item, kv)
		res = append(res, kv)
	}

	return res
}

// SetList 设置n个配置值
func (s *DbConfigService) SetList(listData []dbdto.ConfigKV, typ string) dto.RespData {
	okNum := 0
	failNum := 0
	if typ == "" {
		typ = constant.ConfigTypeDefault
	}
	for _, item := range listData {
		res := s.SetKVT(item.ConfigKey, item.ConfigValue, typ)
		if res.Code == 1 {
			okNum += 1
		} else {
			failNum += 1
		}
	}

	return dto.RespOk(fmt.Sprintf("成功:%v,失败:%v", okNum, failNum), nil)
}

// DelConfig 删除
func (s *DbConfigService) DelConfig(id int) dto.RespData {
	wheres := where.Format(where.Opt("id", "=", id))
	err := s.repo.DeleteByFieldValue(wheres)
	if err != nil {
		return dto.RespError(err.Error())
	}
	return dto.RespOk("ok", nil)

}
func (l *DbConfigService) SaveToCache(k, v string) {

	configCache.Store(k, v)

}
func (l *DbConfigService) ReadByCache(k string) string {
	v, ok := configCache.Load(k)
	if !ok {
		return ""
	}
	val := v.(string)
	return val
}
